//-----------------------------------------------------------------------------
// Filename: SIPParams.cs
//
// Description: SIP parameters as used in Contact, To and Form SIP headers.
//
// History:
// 06 May 2006	Aaron Clauson	Created.
//
// License: 
// This software is licensed under the BSD License http://www.opensource.org/licenses/bsd-license.php
//
// Copyright (c) 2006 Aaron Clauson (aaronc@blueface.ie), Blue Face Ltd, Dublin, Ireland (www.blueface.ie)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that 
// the following conditions are met:
//
// Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
// Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
// disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Blue Face Ltd. 
// nor the names of its contributors may be used to endorse or promote products derived from this software without specific 
// prior written permission. 
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
// POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

using System;
using System.Text.RegularExpressions;
using BlueFace.Security;
using BlueFace.VoIP.Authentication;
using BlueFace.VoIP.Net;
using log4net;

#if UNITTEST
using NUnit.Framework;
#endif

namespace BlueFace.VoIP.Net.SIP
{
	public class SIPParams
	{		
		private const char TAG_DELIMITER = ';';
		private const char TAG_NAME_VALUE_SEPERATOR = '=';
		
		public static string ParseSIPParam(string paramStr, string paramName)
		{			
			if(paramStr != null)
			{
				string[] paramPairs = paramStr.Split(TAG_DELIMITER);

				foreach(string paramPair in paramPairs)
				{
					if(paramPair != null && paramPair.Trim().Length > 0)
					{
						int seperatorPosn = paramPair.IndexOf(TAG_NAME_VALUE_SEPERATOR);
						if(seperatorPosn!= -1)
						{
							string currParamName = paramPair.Substring(0, seperatorPosn);

							// If this is not the paramter that is being removed put it back on.
							if(currParamName == paramName)
							{
								return paramPair.Substring(seperatorPosn+1);
							}
						}
					}
				}
			}

			return null;
		}

		/// <summary>
		/// Removes all instances
		/// </summary>
		/// <param name="paramName">Name of the parameter field to remove.</param>
		/// <returns>A new parameter string with any instances of the required field removed.</returns>
		public static string RemoveSIPParam(string paramStr, string paramName)
		{
			string newParamStr = null;
			
			if(paramStr != null)
			{
				string[] paramPairs = paramStr.Split(TAG_DELIMITER);

				foreach(string paramPair in paramPairs)
				{
					if(paramPair != null && paramPair.Trim().Length > 0)
					{
						int seperatorPosn = paramPair.IndexOf(TAG_NAME_VALUE_SEPERATOR);
						if(seperatorPosn!= -1)
						{
							string paramToCheckName = paramPair.Substring(0, seperatorPosn);

							// If this is not the parameter that is being removed put it back on.
							if(paramToCheckName != paramName)
							{
								newParamStr += (newParamStr == null) ? paramPair : TAG_DELIMITER + paramPair;
							}
						}
						else
						{
							// Invalid parameter. Be forgiving and put it back on.
							newParamStr += TAG_DELIMITER + paramPair;
						}
					}
				}
			}

			return newParamStr;
		}

						
		#region Unit testing.

		#if UNITTEST
	
		[TestFixture]
		public class SIPParamsUnitTest
		{
			[TestFixtureSetUp]
			public void Init()
			{
				
			}

			
			[TestFixtureTearDown]
			public void Dispose()
			{			
				
			}

			
			[Test]
			public void SampleTest()
			{
				Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
				
				Assert.IsTrue(true, "True was false.");
			}

			[Test]
			public void RouteParamExtractTest()
			{
				Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);

				string routeParam = ";lr;server=hippo";
				string serverParam = SIPParams.ParseSIPParam(routeParam, "server");

				Console.WriteLine("The server parameter is=" + serverParam + ".");
				
				Assert.IsTrue(serverParam == "hippo", "The server parameter was not correctly extracted.");
			}

			[Test]
			public void RemoveTagParamTest()
			{
				Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);

				string tagParam = ";lr;tag=1234;server=hippo";
				string noTagParam = SIPParams.RemoveSIPParam(tagParam, "tag");

				Console.WriteLine("The new parameter string is=" + noTagParam + ".");
				
				Assert.IsTrue(noTagParam == ";lr;server=hippo", "The tag parameter was not correctly removed.");
			}

		}

		#endif

		#endregion
	}
}
